/***************************************************************************
 *   Copyright (C) 2007 by Eduardo Robles Elvira   *
 *   edulix@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef KONNTRACKMODEL_H
#define KONNTRACKMODEL_H

#include <QAbstractTableModel>
#include <QVector>
#include <QTimer>
#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack_tcp.h>
#include "common.h"

class QDomElement;
class QDomNode;
class QVariant;
class QModelIndex;
class QItemSelectionModel;
class KonntrackItem;

/**
 * KonntrackModel communicates with libnetfilter_conntrack and provides the data
 * to the conntracks list view. Despite the view is a list, We inherit from
 * QAbstractTableModel because it simplifies much our work.
 *
 * We have a list of items which contains the list of connections tracked. Periodically
 * (using a Qtimer, each second), conntracksPopulate() is called and we ask to
 * conntrack to retrieve the list of connections and the library in turn automatically
 * calls dump_cb(), one conntrack at a time. We retrieve the information about the
 * the connection in XML and parse it.
 *
 * In the future the headers of the model will be able to be rearranged, so we have
 * a hash table that stores in which real column is the information about each real
 * column.
 */
 class KonntrackModel : public QAbstractTableModel
{
	Q_OBJECT

	public:
		/**
		 * Constructor of the Model. Initializes a timer that calls for an update of
		 * the list of conntracks, and initializes the conntrack library enviroment.
		 * @param parent Parent widget
		 */
		KonntrackModel(QObject *parent = 0);
		
		/**
		 * Destructor of the Model. Closes the Netfilter handle
		 */
		~KonntrackModel();
		
		/**
		 * Callback function for conntrack that retrieves one conntrack at a time.
		 * Used to get the conntrack lists in XML. You shouldn't call this function, it's a
		 * callback! Only netfilter is supposed to do so.
		 * @return NFCT_CB_STOLEN which means that we have stolen the given nf_conntrack.
		 */
		static int dump_cb(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data);

		/**
		 * Returns the data stored in #items for the item referred to by the index.
		 * Usually only called by the list view to retrieve information.
		 * @return QVariant() if #index is invalid of #role != Qt::DisplayRole, otherwise
		 * returns the data it was asked for
		 */
		QVariant data(const QModelIndex &index, int role) const;
		QVariant data(const QModelIndex &index, int role, bool translated) const;
		
		/**
		 * Returns the data for the given role and section in the header for horizontal orientation.
		 */
		QVariant headerData(int section, Qt::Orientation orientation,
				    int role = Qt::DisplayRole) const;
		
		/**
		 * Returns the number of items in the model.
		 * @param parent Ignored as we don't implement nesting.
		 */
		int rowCount(const QModelIndex &parent = QModelIndex()) const;
		
		/**
		 * Returns the number of columns in the model, which is always 19 at the moment
		 * (this *will* change in the future)
		 * @param parent Ignored as we don't implement nesting
		 */
		int columnCount(const QModelIndex &parent = QModelIndex()) const;
		
		/**
		 * Change the selection model
		 */
		void setSelectionModel(QItemSelectionModel* selectionModel);

	public slots:
		/**
		 * Updates the conntracks' list
		 */
		void conntracksPopulate();
		
		/**
		 * Delete the selected conntracks
		 */
		void removeSelection();
		
		
		/**
		 * When this function is called it means that an ip's name has been resolved and
		 * that we need to update the model to reflect it.
		 */
		void ipNameResolved();
	
	protected:
		/**
		 * Extracts the information from a conntrack in XML and shows it in conntracks' list
		 * @param string[] Conntrack information in XML
		 * @param ct Conntrack pointer
		 */
		void listConntrack(char string[], nf_conntrack *ct);
		
		/**
		 * Extracks information out of the XML representation of a conntrack
		 * @param meta XML dom
		 */
		void processMeta(QDomElement &meta);
		
		/**
		 * Sets the text for current item (#nextRow)
		 * @param col Column to be set
		 * @param node Contains the text to set
		 */
		void setColText(int col, QDomNode &node);
	
	protected:
		u_int8_t family; /// Used in conntracksPopulate(), in nfct_query()
		struct nfct_handle *h; /// This represent the object we use to communicate with netfilter library
		int nextRow; /// Current item (when updating items' data)
		QTimer *timer; /// Triggers periodically - each second - the update of the conntrack list
		QVector<KonntrackItem*> items; /// The vector of conntrack items
		QItemSelectionModel *selectionModel; /// Selection mode, thanks to which items can be removed nicely
};

#endif
